package com.game.modular.game.battle.process.battleStage.actionPhase.actionPhase2.item;

import com.game.modular.game.battle.panel.Battle;
import com.game.modular.game.battle.panel.attribute.PlayerHeroAttributeServiceImpl;
import com.game.modular.game.battle.process.skillEffectHandle.impl.BloodVolumeStrategy;
import com.game.modular.game.battle.process.skillEffectHandle.impl.StatusStrategy;
import com.game.modular.game.playerAssets.domain.PlayerHero;
import com.game.modular.game.battle.panel.attribute.domain.PlayerHeroAttribute;
import com.game.modular.gameCore.battle.service.impl.CoreCombatFormulaServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 64
 * 普通攻击
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OrdinaryAttackStrategy {
    private final PlayerHeroAttributeServiceImpl attributeService;
    private final CoreCombatFormulaServiceImpl coreCombatFormulaServiceImpl;
    private final ReleaseSkillService releaseSkillService;
    @Resource
    private StatusStrategy.Status45 status45;
    @Resource
    private BloodVolumeStrategy.PhysicsAttackStrategy physicsAttackStrategy;
    @Resource
    private CoreCombatFormulaServiceImpl coreCombatFormulaService;

    public void apply(
            @NotNull(message = "战斗id不能为空") Long battleId,
            @NotNull(message = "回合数") int roundCount,
            @NotNull(message = "出手数") int orderOfAction,
            @NotNull(message = "行动武将不能为空") PlayerHero playerHero,
            @NotNull(message = "当前存活武将") List<PlayerHero> actionList
    ) {

        Battle battle = Battle.get(battleId);

        // 行动方
        PlayerHeroAttribute attribute = attributeService.selectCache(battleId, playerHero.getId());
        attribute.setPhase(22);// 行动阶段

        boolean disarmUsed = attributeService.statusUse(attribute, 24L);// 缴械

        if (!disarmUsed) {
            // 防守方
            List<PlayerHero> defCamp = actionList.stream()
                    .filter(item -> !item.getRankCamp().equals(playerHero.getRankCamp()))
                    .sorted(Comparator.comparing(PlayerHero::getRankOrder))
                    .collect(Collectors.toList());
            if (defCamp.isEmpty()) {
                return;
            }
            PlayerHero defWJ = defCamp.remove(0);
            PlayerHeroAttribute defAttribute = attributeService.selectCache(battleId, defWJ.getId());


            attributeService.saveCache(defAttribute);

            apply(attribute, defAttribute);


            status45.apply(attribute, defWJ, defCamp);
            releaseSkillService.heroReleaseSkills(battleId, roundCount, orderOfAction, playerHero, 4, defCamp);


            boolean doubleHitUsed = attributeService.statusUseAndRefresh(attribute, 37L);// 连击
            while (doubleHitUsed) {
                log.info("连击");
                apply(attribute, defAttribute);
                releaseSkillService.heroReleaseSkills(battleId, roundCount, orderOfAction, playerHero, 4, defCamp);
                doubleHitUsed = attributeService.statusUseAndRefresh(attribute, 37L);
            }

        } else {
            log.error("被缴械");
        }
    }

    /**
     * 发动一次普通攻击伤害
     *
     * @param sourceAttribute 来源英雄属性
     * @param targetAttribute 目标英雄属性
     */
    public void apply(
            PlayerHeroAttribute sourceAttribute,
            PlayerHeroAttribute targetAttribute
    ) {
        Long currentForce = sourceAttribute.getCurrentForce();
        Double att = sourceAttribute.getAtt();
        Double igPhysicalDefense = sourceAttribute.getIgPhysicalDefense();
        double physicsAttackIncrease =
                sourceAttribute.obtainPhysicsAttackIncrease() - targetAttribute.obtainPhysicsAttackDecrease();
        Double def = targetAttribute.getDef();
        double physics = coreCombatFormulaService.getPhysics(
                currentForce,
                att,
                igPhysicalDefense,
                1.0,
                physicsAttackIncrease,
                def
        );
        targetAttribute.attributeUpdate(
                "currentForce",
                -physics,
                0,
                1,
                64L
        );
        sourceAttribute.attributeUpdate(
                "currentForce",
                -physics,
                1,
                1,
                64L
        );
        attributeService.saveCache(sourceAttribute);
        attributeService.saveCache(targetAttribute);
        log.info(
                "普通攻击,武将:{}兵力:{}--->目标:{}-({}){}",
                sourceAttribute.getId(),
                targetAttribute.getCurrentForce(),
                targetAttribute.getId(),
                physics,
                targetAttribute.getCurrentForce());
    }
}
